﻿using AutoMapper;
using Serilog;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using WCS_Entity.Dto.UserDto;
using WCS_Entity.User;
using WCS_Repository.Interface;
using WCS_Repository.Repositories;
using WCS_Service.Interface;
using WCS_Utility.Helper;

namespace WCS_Service.Services
{
    /// <summary>
    /// 用户表 接口实现
    /// </summary>
    public class UserService : BaseService<UsersEntity> , IUserService
    {
        private readonly IUserRepository _userRepository;
        private readonly IRuleRepository _ruleRepository;
        private readonly IMenuRepository _menuRepository;
        private readonly IMapper _mapper;

        public UserService(IUserRepository userRepository,
                           IRuleRepository ruleRepository,
                           IMenuRepository menuRepository,
                           IMapper mapper)
        {
            _userRepository = userRepository;
            base.BaseDal = userRepository;
            _ruleRepository = ruleRepository;
            _menuRepository = menuRepository;
            _mapper = mapper;
        }
        #region 查询指定用户信息
        /// <summary>
        /// 查询指定用户信息
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public async Task<UserDto> QueryUserAsync(int userId)
        {
            UserDto userDto = new UserDto();
            var userInfo = await _userRepository.QueryByIdAsync(userId);
            if (userInfo is null)
            {
                Log.Error($"查询用户{userId}失败");
                return null;
            }
            userDto = _mapper.Map<UserDto>(userInfo);
            var ruleIds = userInfo.ruleIds.Split(',');
            var ruleList = await _ruleRepository.QueryByIDsAsync(ruleIds);
            if (ruleList is not null && ruleList.Any())
            {
                List<Task<RuleDto>> ruleDtos = new List<Task<RuleDto>>();
                ruleList?.ForEach(rule =>
                {
                    ruleDtos.Add(QueryRuleInfoAsync(rule));
                });

                await Task.WhenAll(ruleDtos);
                userDto.Rules = ruleDtos.Select(r => r.Result).ToList();
            }

            return userDto;
        }

        public async Task<UserDto> UpdateUserAsync(UpdateUserDto dto)
        {
            var updateUser = await _userRepository.QueryByIdAsync(dto.userId);
            if (updateUser is null) 
            {
                Log.Error($"更新用户{dto.userName}不存在");
                return null;
            }
            if (updateUser.userName != dto.userName)
            {
                updateUser.userName = dto.userName;
            }
            if (updateUser.avatarImage != dto.avatarImage)
            {
                updateUser.avatarImage = dto.avatarImage;
            }
            if (updateUser.status != dto.status)
            {
                updateUser.status = dto.status;
            }
            var ruleIds = string.Join(",", dto.ruleDtos.Select(r => r.Id));
            if (updateUser.ruleIds != ruleIds)
            {
                updateUser.ruleIds = ruleIds;
            }
            updateUser.updataTime = DateTime.Now;
            var userDto = _mapper.Map<UserDto>(updateUser);
            await _userRepository.UpdateAsync(updateUser);

            return userDto;
        }

        public async Task<UserDto> CreateUserAsync(CreateUserDto dto)
        {
            var flag = await _userRepository.ExistsAsync(u => u.userName == dto.userName);
            if (flag)
            {
                Log.Error("创建用户失败,用户名重复");
                return null;
            }
            var userEntity = _mapper.Map<UsersEntity>(dto);
            userEntity.createTime = DateTime.Now;
            userEntity.passWord = CommonHelper.EnPassword(dto.passWord, userEntity.createTime);
            userEntity.ruleIds = string.Join(",", dto.ruleDtos.Select(r => r.Id));
            await _userRepository.InsertAsync(userEntity);
            var userDto = _mapper.Map<UserDto>(userEntity);
            return userDto;
        }

        public async Task<bool> DeleteUserAsync(int userId)
        {
            return await _userRepository.DeleteByIdAsync(userId);
        }

        public Task<bool> LoginAsync(UserLoginDto dto)
        {
            throw new NotImplementedException();
        }

        public Task<bool> LogoutAsync()
        {
            throw new NotImplementedException();
        }

        public async Task<List<UserDto>> QueryAllUserAsync()
        {
            Expression<Func<UsersEntity, object>> orderEx = p => p.createTime;
            var userList = await _userRepository.QueryPageAsync(null, orderEx, OrderByType.Desc,1,10);
            if (userList is null || !userList.Any())
            {
                Log.Error("查询所有用户失败!");
                return null;
            }
            List<Task<UserDto>> useDtos = new List<Task<UserDto>>();
            List<UserDto> result = new List<UserDto>(); 
            foreach (var user in userList)
            {
                useDtos.Add(QueryUserInfoAsync(user));
            }
            await Task.WhenAll(useDtos);
            result = useDtos.Select(x => x.Result).ToList();
            return result;
        }

        public async Task<Tuple<bool,string>> UpdatePwdAsync(int userId, string newPwd, string oldPwd)
        {
            var userEntity = await _userRepository.QueryByIdAsync(userId);
            if (userEntity is null)
            {
                Log.Error($"修改密码用户{userId}不存在");
                return Tuple.Create<bool,string>(false, "修改密码的用户不存在");
            }
            var oldPwdStr = CommonHelper.EnPassword(oldPwd,userEntity.createTime);
            if (oldPwdStr != userEntity.passWord)
            {
                Log.Error($"修改密码用户{userId},旧密码输入错误");
                return Tuple.Create<bool, string>(false, "旧密码输入错误");
            }
            var newPwdStr = CommonHelper.EnPassword(newPwd,userEntity.createTime);
            userEntity.passWord = newPwdStr;
            userEntity.updataTime = DateTime.Now;
            var flag = await _userRepository.UpdateAsync(userEntity);
            return Tuple.Create<bool, string>(flag, "密码修改错误");
        }

        #region Private

        private async Task<UserDto> QueryUserInfoAsync(UsersEntity entity)
        { 
            var roleIds = entity.ruleIds.Split(',');
            var result = _mapper.Map<UserDto>(entity);
            List<RuleDto> rules = new List<RuleDto>();
            var ruleInfoList = await _ruleRepository.QueryByIDsAsync(roleIds);
            if (ruleInfoList is not null && ruleInfoList.Any())
            {
                List<Task<RuleDto>> ruleDtos = new List<Task<RuleDto>>();
                foreach (var rule in ruleInfoList)
                {
                    ruleDtos.Add(QueryRuleInfoAsync(rule));
                }

                await Task.WhenAll(ruleDtos);
                rules = ruleDtos.Select(r => r.Result).ToList();
            }
            result.Rules = rules;

            return result;
        }

        /// <summary>
        /// 转换角色信息
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        private async Task<RuleDto> QueryRuleInfoAsync(RulesEntity entity)
        {
            RuleDto ruleDto = new RuleDto();
            var menuIdArray = entity.menuIds.Split(',');
            if (menuIdArray is null)
            { 
                return _mapper.Map<RuleDto>(entity);
            }
            var menuInfoList = await _menuRepository.QueryByIDsAsync(menuIdArray);
            ruleDto.MenuName = menuInfoList?.Select(m => m.name)?.ToList() ?? new List<string>();
            return ruleDto;
        }
        #endregion
        #endregion
    }
}
